/*
 * Middleware
 * Copyright (C) 2010/11
 * Riccardo Pulvirenti, Giuseppe Ravidà, Andrea Tino
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANDABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses
 */

/*!
 * File: task_proxy_factory.hpp
 */

#ifndef _TASK_PROXY_FACTORY_HPP_
#define _TASK_PROXY_FACTORY_HPP_

#include <iostream>
#include <string>

#include "task_manager_proxy.hpp"

//-----------------------------------------------------------------------------
// Struct, enums
namespace middleware {
/*! \enum TaskProxyDirection
 * Determines the mode of the returned proxy.
 */
typedef enum {
	/*!
	 * Factory will return a TaskManagerProxy ready for sending TaskDescriptor.
	 */
	kSendTaskProxy = 0,
	/*!
	 * Factory will return a TaskManagerProxy ready for receiving TaskDescriptor.
	 */
	kReceiveTaskProxy = 1
} TaskProxyDirection;
}
//-----------------------------------------------------------------------------
// Class definitions
namespace middleware {
/*! \class TaskProxyFactory
 * \brief Instantiating a TaskManagerProxy object.
 *
 * Manages instantiation of a TaskManagerProxy object.
 */
class TaskProxyFactory {
public:
	/*!
	 * Constructs a factory by specifying what kind of proxy it will return and,
	 * depending by the mode, all network parameters necessary to contact
	 * the other Manager for sending a TaskDescriptor or to bind in order to
	 * receive a TaskDescriptor from another Manager.
	 * \param dir TaskProxyDirection specifying what kind of TaskManagerProxy
	 * return (send-ready or receive-ready proxy).
	 * \param send_or_bind_ip Ip v4 address specifying where to send or where
	 * to bind to receive a TaskDescriptor.
	 * \param send_or_bind_port TCP port specifying where to send or where
	 * to bind to receive a TaskDescriptor.
	 */
	TaskProxyFactory(TaskProxyDirection dir, std::string send_or_bind_ip,
			std::string send_or_bind_port);
	/*!
	 * Constructs a full featured factory able to return a full featured
	 * TaskManagerProxy in order to send and receive a TaskDescriptor.
	 * \param send_ip Ip v4 address specifying where to send a TaskDescriptor.
	 * \param bind_ip Ip v4 address specifying where to bind in order to listen
	 * for an incoming TaskDescriptor.
	 * \param send_port TCP port specifying where to send a TaskDescriptor.
	 * \param bind_port TCP Port specifying where to bind in order to listen
	 * for an incoming TaskDescriptor.
	 */
	TaskProxyFactory(std::string send_ip, std::string send_port,
			std::string bind_ip, std::string bind_port);
	/*!
	 * Destroys factory. When factory encounters destructor, dynamic allocated
	 * memory for proxy is AUTOMATICALLY released; when a factory dies, its
	 * proxy is deleted. This happens also when factory is called to get
	 * a proxy more than one time.
	 */
	~TaskProxyFactory();
	/*!
	 * Gets proxy: attention, a new instance is created via dynamic allocation.
	 * If a previous proxy was generated, it will be detroyed.
	 */
	TaskManagerProxy* getProxy();
private:
	/*!
	 * Holds built proxy. If the factory is detroyed, then so is the proxy.
	 */
	TaskManagerProxy* _proxy;
	/*!
	 * Configuration parameter: Ip to send tasks to.
	 */
	std::string _send_ip;
	/*!
	 * Configuration parameter: Port to send tasks to.
	 */
	std::string _send_port;
	/*!
	 * Configuration parameter: Ip to bind to listen to tasks.
	 */
	std::string _bind_ip;
	/*!
	 * Configuration parameter: Port to bind to listen to tasks.
	 */
	std::string _bind_port;
}; /* TaskProxyFactory */
} /* middleware */

#endif
